﻿using System;
using System.Runtime.Serialization;
using System.Reflection;
using System.IO;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace Muccu.Contracts
{
    [DataContract]
    public class Request
    {
        [DataMember(Name = "jsonrpc")]
        public string JsonRpc { get; set; }

        [DataMember(Name = "method")]
        public string Method { get; set; }

        [DataMember(Name = "params")]
        public object[] Parameters { get; set; }

        [DataMember(Name = "id")]
        public int Id { get; set; }

        [DataMember(Name = "ticket")]
        public string Ticket { get; set; }

        public static object[] ConvertParameters(ParameterInfo[] infos, object[] parameters)
        {
            if (infos.Length != parameters.Length)
                throw new ArgumentException("Wrong number of arguments");

            var parsedParameters = new object[infos.Length];

            for (int i = 0; i < infos.Length; i++)
            {
                object value = parameters[i];
                Type conversionType = infos[i].ParameterType;
                try
                {
                    if (value is JObject)
                        parsedParameters[i] = value as dynamic;
                    else
                        parsedParameters[i] = Convert.ChangeType(value, conversionType);
                }
                catch (FormatException ex)
                {
                    throw new ArgumentException(string.Format("Method argument has wrong format: {0}", value), infos[i].Name, ex);
                }
                catch(InvalidCastException ex)
                {
                    throw new ArgumentException("Method argument was Null and can't convert to ValueType", infos[i].Name, ex);
                }
            }

            return parsedParameters;
        }

        public static Request FromStream(Stream stream)
        {
            StreamReader sr = new StreamReader(stream);
            return JsonConvert.DeserializeObject<Request>(sr.ReadToEnd());
        }

    }
}
